package main

import (
	"context"
	"flag"
	"net"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"

	"github.com/Terry-Mao/goim/internal/logic"
	"github.com/Terry-Mao/goim/internal/logic/conf"
	"github.com/Terry-Mao/goim/internal/logic/grpc"
	"github.com/Terry-Mao/goim/internal/logic/http"
	"github.com/Terry-Mao/goim/internal/logic/model"
	"github.com/Terry-Mao/goim/internal/registry"
	etcdRegistry "github.com/Terry-Mao/goim/internal/registry/etcd"
	log "github.com/golang/glog"
	clientv3 "go.etcd.io/etcd/client/v3"
)

const (
	ver   = "2.0.0"
	appid = "goim.logic"
)

func main() {
	flag.Parse()
	if err := conf.Init(); err != nil {
		panic(err)
	}
	log.Infof("goim-logic [version: %s env: %+v] start", ver, conf.Conf.Env)

	// 注册中心
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"192.168.34.4:2379"},
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		panic(err)
	}
	rs, err := etcdRegistry.NewRegistry(cli)
	if err != nil {
		panic(err)
	}

	// logic
	srv := logic.New(conf.Conf, rs)
	// 提供管理接口
	httpSrv := http.New(conf.Conf.HTTPServer, srv)
	// grpc 服务
	rpcSrv := grpc.New(conf.Conf.RPCServer, srv)

	// 把自己上报到注册中心
	ins := register(rs)

	// signal
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
	for {
		s := <-c
		log.Infof("goim-logic get a signal %s", s.String())
		switch s {
		case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
			rs.UnRegister(context.Background(), ins)
			rs.Close()
			srv.Close()
			httpSrv.Close()
			rpcSrv.GracefulStop()
			log.Infof("goim-logic [version: %s] exit", ver)
			log.Flush()
			return
		case syscall.SIGHUP:
		default:
			return
		}
	}
}

func register(rs registry.Registry) *registry.ServiceInstance {
	env := conf.Conf.Env
	// addr := ip.InternalIP()
	addr := "192.168.34.4"
	_, port, _ := net.SplitHostPort(conf.Conf.RPCServer.Addr)
	ins := &registry.ServiceInstance{
		Region:   env.Region,
		Zone:     env.Zone,
		Env:      env.DeployEnv,
		Hostname: env.Host,
		AppID:    appid,
		Addrs: []string{
			"grpc://" + addr + ":" + port,
		},
		Metadata: map[string]string{
			model.MetaWeight: strconv.FormatInt(env.Weight, 10),
		},
	}
	err := rs.Register(context.Background(), ins)
	if err != nil {
		panic(err)
	}
	return ins
}
